//package com.thwj.common.utils.pay;
//
//
//import com.alibaba.fastjson.JSONObject;
//import com.thwj.common.utils.StringUtils;
//import com.thwj.common.utils.http.HttpUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//import org.w3c.dom.Node;
//import org.w3c.dom.NodeList;
//
//import javax.annotation.PostConstruct;
//import javax.net.ssl.KeyManagerFactory;
//import javax.xml.parsers.DocumentBuilder;
//import javax.xml.transform.OutputKeys;
//import javax.xml.transform.Transformer;
//import javax.xml.transform.TransformerFactory;
//import javax.xml.transform.dom.DOMSource;
//import javax.xml.transform.stream.StreamResult;
//import java.io.*;
//import java.security.*;
//import java.security.cert.CertificateException;
//import java.util.Arrays;
//import java.util.HashMap;
//import java.util.Map;
//import java.util.Set;
//
//import static com.thwj.common.utils.StringUtils.getRandomString;
//
//
//@Component
//public class WXH5PayUtils {
//
//
//    @Autowired
//    private WXPayConfig wxPayConfig;
//
//
//    /**
//     * 初始化获取配置
//     */
//    @PostConstruct
//    public void init() {
//        wxPayConfig = this.wxPayConfig;
//    }
//
//
//    private static final Logger logger = LoggerFactory.getLogger(WXH5PayUtils.class);
//
//    /**
//     * 统一下单方法
//     */
//    public Map<String, String> unifieOorder(String outTradeNo, Long totalFee, String openid) {
//        JSONObject payJson = addPayJson(outTradeNo, totalFee, openid);
//        Map<String, String> paramsMap = jsonToMap(payJson);
//        String signStr = generateSignature(paramsMap, wxPayConfig.getApiV2());
//        if (StringUtils.isNull(signStr)) {
//            Map<String, String> returnMap = new HashMap<>();
//            returnMap.put("return_code", "FAIL");
//            returnMap.put("return_msg", "获取签名失败");
//            return returnMap;
//        }
//        paramsMap.put("sign", signStr);
//
//        String payxml = null;
//        try {
//            payxml = mapToXml(paramsMap);
//        } catch (Exception e) {
//            logger.error(e.toString());
//            Map<String, String> returnMap = new HashMap<>();
//            returnMap.put("return_code", "FAIL");
//            returnMap.put("return_msg", "map转xml失败");
//            return returnMap;
//
//        }
//        logger.info(payxml);
//        String PayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
//
//        String resxml = HttpUtils.sendPost(PayUrl, payxml, "UTF-8");
//        Map<String, String> resMap = null;
//        try {
//            resMap = xmlToMap(resxml);
//        } catch (Exception e) {
//            logger.error(e.toString());
//            Map<String, String> returnMap = new HashMap<>();
//            returnMap.put("return_code", "FAIL");
//            returnMap.put("return_msg", "xml转map失败");
//            return returnMap;
//        }
//
//        return resMap;
//
//    }
//
//
//    /**
//     * 退款方法
//     */
//    public Map<String, String> refundOorder(String outTradeNo, String outRefundNo, Long totalFee, Long refundFee) {
//        JSONObject payJson = refundJson(outTradeNo, outRefundNo, totalFee, refundFee);
//        Map<String, String> paramsMap = jsonToMap(payJson);
//        String signStr = generateSignature(paramsMap, wxPayConfig.getApiV2());
//        if (StringUtils.isNull(signStr)) {
//            Map<String, String> returnMap = new HashMap<>();
//            returnMap.put("return_code", "FAIL");
//            returnMap.put("return_msg", "获取签名失败");
//            return returnMap;
//        }
//        paramsMap.put("sign", signStr);
//
//        String payxml = null;
//        try {
//            payxml = mapToXml(paramsMap);
//        } catch (Exception e) {
//            logger.error(e.toString());
//            Map<String, String> returnMap = new HashMap<>();
//            returnMap.put("return_code", "FAIL");
//            returnMap.put("return_msg", "map转xml失败");
//            return returnMap;
//
//        }
//        logger.info(payxml);
//        String refundUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
//        String resxml = null;
//        try {
//            KeyManagerFactory kmf = getPriKeyPkcs12();
//            resxml = HttpUtils.sendPostWithCert(refundUrl, null, payxml, 6 * 1000, 8 * 1000, kmf);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        Map<String, String> resMap = null;
//        try {
//            resMap = xmlToMap(resxml);
//        } catch (Exception e) {
//            logger.error(e.toString());
//            Map<String, String> returnMap = new HashMap<>();
//            returnMap.put("return_code", "FAIL");
//            returnMap.put("return_msg", "xml转map失败");
//            return returnMap;
//        }
//
//        return resMap;
//    }
//
//
//    public KeyManagerFactory getPriKeyPkcs12() {
//        byte[] certData;
//        // 证书
//        char[] password = wxPayConfig.getMchId().toCharArray();
//        String certPath = this.getClass().getClassLoader().getResource("keyFiles/apiclient_cert.p12").getPath();
//        File file = new File(certPath);
//        if (!file.exists()) {
//            certPath = "/opt/limao/keyFiles/apiclient_cert.p12";
//            file = new File(certPath);
//        }
//
//        InputStream certStream = null;
//        ByteArrayInputStream certBis = null;
//        try {
//            certStream = new FileInputStream(file);
//            certData = new byte[(int) file.length()];
//            certStream.read(certData);
//            certStream.close();
//            certBis = new ByteArrayInputStream(certData);
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        KeyStore ks = null;
//        KeyManagerFactory kmf = null;
//        try {
//            ks = KeyStore.getInstance("PKCS12");
//            ks.load(certBis, password);
//            // 实例化密钥库 & 初始化密钥工厂
//            kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
//            kmf.init(ks, password);
//        } catch (KeyStoreException e) {
//            e.printStackTrace();
//        } catch (UnrecoverableKeyException e) {
//            e.printStackTrace();
//        } catch (CertificateException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        } catch (NoSuchAlgorithmException e) {
//            e.printStackTrace();
//        }
//
//        return kmf;
//    }
//
//
//    /**
//     * 统一下单Json
//     */
//    public JSONObject addPayJson(String outTradeNo, Long totalFee, String openid) {
//        JSONObject json = initJSONObject();
//        json.put("body", "陪玩订单");
//        json.put("out_trade_no", outTradeNo);
//        json.put("fee_type", "CNY");
//        json.put("total_fee", totalFee);
//        json.put("spbill_create_ip", wxPayConfig.getSpbillCreateIp());
//        json.put("trade_type", "JSAPI");
//        json.put("openid", openid);
//        json.put("notify_url", wxPayConfig.getNotifyUrl());
//        json.put("version", "1.0");
//
//        return json;
//    }
//
//
//    /**
//     * 统一下单Json
//     */
//    public JSONObject refundJson(String outTradeNo, String outRefundNo, Long totalFee, Long refundFee) {
//        JSONObject json = initJSONObject();
//        json.put("out_trade_no", outTradeNo);
//        json.put("out_refund_no", outRefundNo);
//        json.put("total_fee", totalFee);
//        json.put("refund_fee", refundFee);
//        return json;
//    }
//
//    /**
//     * 初始化json
//     */
//    public JSONObject initJSONObject() {
//        JSONObject json = new JSONObject();
//        json.put("appid", wxPayConfig.getH5Appid());
//        json.put("mch_id", wxPayConfig.getMchId());
//        json.put("nonce_str", getRandomString(28));
//        json.put("sign_type", "MD5");
//
//        return json;
//    }
//
//
//    /**
//     * 生成签名. 注意，若含有sign_type字段，必须和signType参数保持一致。
//     *
//     * @param data 待签名数据
//     * @param key  API密钥
//     * @return 签名
//     */
//    public static String generateSignature(final Map<String, String> data, String key) {
//        Set<String> keySet = data.keySet();
//        String[] keyArray = keySet.toArray(new String[keySet.size()]);
//        Arrays.sort(keyArray);
//        StringBuilder sb = new StringBuilder();
//        for (String k : keyArray) {
//            if (k.equals("sign")) {
//                continue;
//            }
//            if (data.get(k).trim().length() > 0) // 参数值为空，则不参与签名
//                sb.append(k).append("=").append(data.get(k).trim()).append("&");
//        }
//        sb.append("key=").append(key);
//        try {
//            return MD5(sb.toString()).toUpperCase();
//        } catch (Exception e) {
//            e.printStackTrace();
//            return null;
//
//        }
//
//    }
//
//
//    /**
//     * 生成 MD5
//     *
//     * @param data 待处理数据
//     * @return MD5结果
//     */
//    public static String MD5(String data) throws Exception {
//        java.security.MessageDigest md = MessageDigest.getInstance("MD5");
//        byte[] array = md.digest(data.getBytes("UTF-8"));
//        StringBuilder sb = new StringBuilder();
//        for (byte item : array) {
//            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
//        }
//        return sb.toString().toUpperCase();
//    }
//
//
//    /**
//     * 据编码类型获得签名内容byte[]
//     */
//
//    private byte[] getContentBytes(String content) {
//        try {
//            return content.getBytes("UTF-8");
//        } catch (UnsupportedEncodingException e) {
//            throw new RuntimeException("签名过程中出现错误");
//        }
//    }
//
//    /**
//     * 使json-lib来进行json到map的转换，fastjson有排序问题，不能用
//     */
//
//    public Map<String, String> jsonToMap(JSONObject json) {
//        Map<String, String> map = new HashMap<>();
//        for (Object key : json.keySet()) {
//            String value = json.getString((String) key);
//            map.put((String) key, value);
//        }
//        return map;
//    }
//
//
//    /**
//     * XML格式字符串转换为Map
//     *
//     * @param strXML XML字符串
//     * @return XML数据转换后的Map
//     * @throws Exception
//     */
//    public static Map<String, String> xmlToMap(String strXML) throws Exception {
//        try {
//            Map<String, String> data = new HashMap<String, String>();
//            DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();
//            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
//            org.w3c.dom.Document doc = documentBuilder.parse(stream);
//            doc.getDocumentElement().normalize();
//            NodeList nodeList = doc.getDocumentElement().getChildNodes();
//            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
//                Node node = nodeList.item(idx);
//                if (node.getNodeType() == Node.ELEMENT_NODE) {
//                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
//                    data.put(element.getNodeName(), element.getTextContent());
//                }
//            }
//            try {
//                stream.close();
//            } catch (Exception ex) {
//                // do nothing
//            }
//            return data;
//        } catch (Exception ex) {
//            logger.error("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
//            throw ex;
//        }
//
//    }
//
//    /**
//     * 将Map转换为XML格式的字符串
//     *
//     * @param data Map类型数据
//     * @return XML格式的字符串
//     * @throws Exception
//     */
//    public static String mapToXml(Map<String, String> data) throws Exception {
//        org.w3c.dom.Document document = WXPayXmlUtil.newDocument();
//        org.w3c.dom.Element root = document.createElement("xml");
//        document.appendChild(root);
//        for (String key : data.keySet()) {
//            String value = data.get(key);
//            if (value == null) {
//                value = "";
//            }
//            value = value.trim();
//            org.w3c.dom.Element filed = document.createElement(key);
//            filed.appendChild(document.createTextNode(value));
//            root.appendChild(filed);
//        }
//        TransformerFactory tf = TransformerFactory.newInstance();
//        Transformer transformer = tf.newTransformer();
//        DOMSource source = new DOMSource(document);
//        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
//        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//        StringWriter writer = new StringWriter();
//        StreamResult result = new StreamResult(writer);
//        transformer.transform(source, result);
//        String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
//        try {
//            writer.close();
//        } catch (Exception ex) {
//        }
//        return output;
//    }
//
//
//}
